home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GRAPHICS
/
GIF2RPC.SPK
/
source
/
16bpp_66bit
/
c
/
sierra2
< prev
next >
Wrap
Text File
|
1995-10-16
|
4KB
|
114 lines
/* sierra2.c
* AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
* LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
*
* filter: * 4 3
* 1 2 3 2 1 (1/16)
*/
#include "internal.h"
#include <assert.h>
#include <string.h> /* memset() */
#include <stdlib.h> /* calloc() */
#include "OS:hourglass.h"
#include "OS:macros.h"
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
extern bool process_gif_16bpp_sierra2_66bit(
const process_gif *p) {
byte *rove;
int width, height;
int x, y;
const os_colour *palette;
int line_length;
int *buffer, *this_row, *next_row;
int buffer_width;
int r, g, b;
int or, og, ob;
int t;
int er, eg, eb;
assert(p);
assert(p->pixel_width > 0);
assert(p->pixel_height > 0);
assert(p->in_palette.colours);
/*
* sierra2 requires storing error info for two pixels to right and two pixels to left
* so we will just allocate two extra columns for each row and not do any edge checks
* each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
*/
buffer_width = (2 + p->pixel_width + 2) * 3;
buffer = calloc(1, sizeof(*buffer) * (buffer_width * 2));
if (!buffer) {
/*
* oh dear
*/
return TRUE;
}
initialise_scaling_tables();
/*
* not we pre-load values from the process_gif array
* because it considerably helps the compiler produce better code
*/
rove = p->buffer;
width = p->pixel_width;
height = p->pixel_height;
palette = p->in_palette.colours;
line_length = p->line_length;
for (y= height; (y > 0); y--) {
if ((y & 7) == 0) {
xhourglass_percentage((y * 100) / height);
}
this_row = buffer + (buffer_width * ((y + 2) % 2)) + 2*3;
next_row = buffer + (buffer_width * ((y + 1) % 2)) + 2*3;
/* bottom row has no errors */
memset(next_row, 0, sizeof(*next_row) * (buffer_width - 2*3));
/*
* note that just because we are actually scanning/outputting right to left
* doesn't matter as far as the filter is concerned
* although it might help if we could ``snake''
*/
for (x= width - 1; (x >= 0); x--) {
INPUT;
r += *this_row++; /* add in errors from all rows */
g += *this_row++;
b += *this_row++;
PROCESS;
r -= or; g -= og; b-= ob; /* error */
er = (r * 4) / 16; eg = (g * 4) / 16; eb = (b * 4) / 16;
this_row[ 0] += er; this_row[ 1] += eg; this_row[ 2] += eb; /* this[ 1] += 4/16 */
or = r - er; g = og - eg; ob = b - eb; /* remainder of error */
er >>= 1; eg >>= 1; eb >>= 1;
next_row[ 3] += er; next_row[ 4] += eg; next_row[ 5] += eb; /* next[ 1] += 2/16 */
next_row[-3] += er; next_row[-2] += eg; next_row[-1] += eb; /* next[-1] += 2/16 */
or -= 2 * er; og -= 2 * eg; ob -= 2 * eb;
er >>= 1; eg >>= 1; eb >>= 1;
next_row[-6] += er; next_row[-5] += eg; next_row[-4] += eb; /* next[-2] += 1/16 */
or -= er; og -= eg; ob -= eb;
er = (r * 3) / 16; eg = (g * 3) / 16; eb = (b * 3) / 16;
this_row[ 3] += er; this_row[ 4] += eg; this_row[ 5] += eb; /* this[ 2] += 3/16 */
next_row[ 0] += er; next_row[ 1] += eg; next_row[ 2] += eb; /* next[ 0] += 3/16 */
or -= 2 * er; og -= 2*eg; ob -= 2*eb;
next_row[ 6] += or; next_row[ 7] += og; next_row[ 8] += ob; /* next[ 2] += 1/16 */
next_row += 3; /* adjust next_row pointer */
}
rove += line_length;
}
free(buffer);
return FALSE;
}